#if ZDCONF_WME_SUPPORT == 1
#include "zd1205.h"
extern zd_80211Obj_t dot11Obj;
enum{
    WMM_BE,
    WMM_BK,
    WMM_VI,
    WMM_VO
};
int Exp[] = {1,1,3,7,15,31,63,127,254,511,1023};
int Q_TxCnt[4]={0,  0, 0, 0};
U8 *QIFS;
U8 *Qmin;
U8 *Qmax;
U8 Qcur[4] = {0,0,0,0};
int Qboff[4] = {0 , 0, 0, 0};

int getMinBoff(int *argc, int *argv)
{
    int cIdx = 0;
    int i, minQ = 0,minV = Qboff[0];
    for(i=1;i<4;i++)
    {
        if(Qboff[i] < minV)
        {
            minQ = i;
            minV = Qboff[i];
        }
    }

    *argc = 1;
    argv[*argc-1] = minQ;

    for(i=0;i<4;i++)
    {
        if(i == minQ)
            continue;
        else
        {
            if(minV >=  Qboff[i])
            {
                (*argc)++;
                argv[(*argc)-1]  = i;
            }
        }
    }
    if((*argc) > 1)
        return -1;
    else
        return minQ;

}
int myRand( int j)
{
    unsigned long num;
    num = dot11Obj.Rand(jiffies);
    num %= j;
    return num;
}
int WME_QChoose(struct zd1205_private *macp, U8 validBM)
{
    int i, argc=0, argv[4];
    int minBoff, minBoffV;
    int loopCheck=0;
    for(i=0;i<4;i++)
    {
        QIFS  = macp->WME_staAIFS;
        Qmin  = macp->WME_staCWmin;
        Qmax  = macp->WME_staCWmax;
        if(Qcur[i] == 0)
            Qcur[i]  = Qmin[i];
        if(!(validBM & ( 1 << i)))
            Qboff[i] = 0xFFFF ;
        else 
        {
            if(Qboff[i] > 0x1000)
                Qboff[i] = 0;
        }
    }
again:
    argc = 0;
    if(loopCheck++ > 100)
    {
        while(loopCheck--)
        {
            printk("QChoose failed for %d times\n",loopCheck);
            printk("Q_TxCnt[0]=%d,Q_TxCnt[1]=%d,Q_TxCnt[2]=%d,Q_TxCnt[3]=%d\n",
                    Q_TxCnt[0],Q_TxCnt[1],Q_TxCnt[2],Q_TxCnt[3]);
            printk("Qboff[0]=%d,Qboff[1]=%d,Qboff[2]=%d,Qboff[3]=%d\n",
                    Qboff[0],Qboff[1],Qboff[2],Qboff[3]);
            printk("Qcur[0]=%d,Qcur[1]=%d,Qcur[2]=%d,Qcur[3]=%d\n",
                    Qcur[0],Qcur[1],Qcur[2],Qcur[3]);
            printk("MyRand=%d\n", myRand(1000000000));
            printk("Qmin[0]=%d,Qmin[1]=%d,Qmin[2]=%d,Qmin[3]=%d\n",
                    Qmin[0],Qmin[1],Qmin[2],Qmin[3]);
            printk("Qmax[0]=%d,Qmax[1]=%d,Qmax[2]=%d,Qmax[3]=%d\n",
                    Qmax[0],Qmax[1],Qmax[2],Qmax[3]);
        }
        return 0;
    }
    for(i=0;i<4;i++)
        argv[i] = 0;

    for(i=0;i<4;i++)
    {
        if(Qboff[i] == 0)
            Qboff[i] = myRand(Exp[Qcur[i]]);
    }
    for(i=0;i<4;i++)
        Qboff[i] += QIFS[i];
    
    minBoff = getMinBoff(&argc, argv);
    if (minBoff != -1)
    {
        minBoffV = Qboff[minBoff];
        for(i=0;i<4;i++)
            Qboff[i] -=  minBoffV;
        Qcur[minBoff] = Qmin[minBoff];
        return minBoff;
    }
    else
    {
        minBoffV = Qboff[argv[0]];
        for(i=0;i<4;i++)
        {
            Qboff[i] -= minBoffV;
            if(Qboff[i] == 0)
            {
                Qcur[i]++;
                if(Qcur[i] > Qmax[i])
                    Qcur[i] = Qmax[i];
            }
        }
        goto again;
        
    }

    
}
#if 0
#define RUN 1000000
int main()
{
    int i;
    srand(time(NULL));
    for(i=0;i<RUN;i++)
        Q_TxCnt[makeDecision()]++;
    printf("Q1 = %f%\n", (float)Q_TxCnt[0]*100/RUN);
    printf("Q2 = %f%\n", (float)Q_TxCnt[1]*100/RUN);
    printf("Q3 = %f%\n", (float)Q_TxCnt[2]*100/RUN);
    printf("Q4 = %f%\n", (float)Q_TxCnt[3]*100/RUN);
     
}
#endif

#endif
